using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using DeepSeekChatApp.Models;
using System.Threading.Tasks;
using System.IO;
using Microsoft.Extensions.Logging;
using System;
using System.Text.Json.Serialization;

namespace DeepSeekChatApp.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ChatController : ControllerBase
    {
        private readonly IConfiguration _configuration;
        private readonly ILogger<ChatController> _logger;

        public ChatController(IConfiguration configuration, ILogger<ChatController> logger)
        {
            _configuration = configuration;
            _logger = logger;
        }

        public record ChatMessage(string role, string content);
        public record ChatRequest(List<ChatMessage> messages, bool stream);

        [HttpPost("stream")]
        public async Task StreamChat([FromBody] ChatRequest request)
        {
            var apiKey = _configuration["DeepSeek:ApiKey"];
            var apiUrl = _configuration["DeepSeek:ApiUrl"];
            // 从配置读取 model，未配置时使用合理默认
            var model = _configuration["DeepSeek:Model"] ?? "gpt-4o-mini";

            // 确保响应是流式的
            Response.Headers.Append("Content-Type", "text/event-stream");
            Response.Headers.Append("Cache-Control", "no-cache");
            Response.Headers.Append("Connection", "keep-alive");
            // 对于某些反向代理 (nginx)，可禁止代理缓冲：
            Response.Headers.Append("X-Accel-Buffering", "no");

            _logger.LogInformation("接收到聊天请求，正在处理...");

            try
            {
                using var client = new HttpClient();
                client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", apiKey);

                // 构造发送给外部模型API的标准请求体（确保包含必需的 model 字段）
                var payload = new
                {
                    model = model,
                    messages = request.messages,
                    stream = request.stream
                };

                var jsonOptions = new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
                };

                var jsonRequest = JsonSerializer.Serialize(payload, jsonOptions);
                _logger.LogInformation($"发送到DeepSeek API的请求: {jsonRequest}");

                var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json");

                // 使用 HttpRequestMessage + SendAsync（支持 HttpCompletionOption + CancellationToken）
                using var requestMessage = new HttpRequestMessage(HttpMethod.Post, apiUrl) { Content = content };
                using var response = await client.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, HttpContext.RequestAborted);

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    _logger.LogError($"DeepSeek API返回错误: 状态码={response.StatusCode}, 错误内容={errorContent}");

                    // 向客户端发送错误信息（SSE 格式）
                    await Response.WriteAsync($"data: {{\"error\":\"API调用失败: {response.StatusCode}\",\"details\":\"{errorContent.Replace('"', '\'')}\"}}\n\n");
                    await Response.Body.FlushAsync(HttpContext.RequestAborted);
                    return;
                }

                _logger.LogInformation("DeepSeek API调用成功，开始接收流式响应");

                using var stream = await response.Content.ReadAsStreamAsync(HttpContext.RequestAborted);
                using var reader = new StreamReader(stream);

                _logger.LogInformation("开始读取流式响应数据...");
                int chunkCount = 0;
                StringBuilder fullResponse = new StringBuilder();

                while (!reader.EndOfStream && !HttpContext.RequestAborted.IsCancellationRequested)
                {
                    var line = await reader.ReadLineAsync();
                    _logger.LogInformation($"接收到响应行: {(line == null ? "null" : (line.Length > 200 ? line.Substring(0, 200) + "..." : line))}");

                    if (string.IsNullOrEmpty(line)) continue;

                    if (line.StartsWith("data: "))
                    {
                        chunkCount++;
                        var data = line.Substring(6);
                        _logger.LogInformation($"处理数据块 #{chunkCount}: {(data.Length > 200 ? data.Substring(0, 200) + "..." : data)}");

                        fullResponse.AppendLine(data);

                        if (data == "[DONE]")
                        {
                            _logger.LogInformation("接收到完成标记[DONE]");
                            // 将结束标记转发给前端（前端已有处理）
                            await Response.WriteAsync($"data: [DONE]\n\n");
                            await Response.Body.FlushAsync(HttpContext.RequestAborted);
                            break;
                        }

                        try
                        {
                            // 立即将后端流片段按 SSE 格式转发给前端
                            await Response.WriteAsync($"data: {data}\n\n");
                            await Response.Body.FlushAsync(HttpContext.RequestAborted);
                            _logger.LogInformation("数据发送成功");
                        }
                        catch (Exception ex)
                        {
                            // 客户端断开连接或写入失败
                            _logger.LogWarning($"客户端断开连接或发送失败: {ex.Message}");
                            break;
                        }
                    }
                    else
                    {
                        _logger.LogInformation($"忽略非 data 行: {line}");
                    }
                }

                _logger.LogInformation($"流处理结束，共接收 {chunkCount} 个数据块。");
            }
            catch (OperationCanceledException)
            {
                _logger.LogWarning("请求已取消（客户端关闭连接或超时）。");
            }
            catch (Exception ex)
            {
                _logger.LogError($"处理聊天请求时发生异常: {ex.Message}", ex);

                try
                {
                    // 向客户端发送错误信息（SSE 格式）
                    await Response.WriteAsync($"data: {{\"error\":\"处理请求时发生错误: {ex.Message.Replace('"', '\'')}\"}}\n\n");
                    await Response.Body.FlushAsync();
                }
                catch { }
            }
        }
    }
}